home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / hardware.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  7KB  |  234 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         Hardware                                                   }
  4. {                                                                            }
  5. { DESCRIPTION:    An UNIT that provides general support to generic Hardware, }
  6. {                 like the PIC, the DMA controller, etc...                   }
  7. {                                                                            }
  8. { AUTHOR:         Juan Carlos Arévalo                                        }
  9. {                                                                            }
  10. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  11. {                                                                            }
  12. { HISTORY:        18-Nov-1992 Documentation.                                 }
  13. {                                                                            }
  14. { (C) 1992 VangeliSTeam                                                      }
  15. {____________________________________________________________________________}
  16.  
  17. UNIT Hardware;
  18.  
  19. INTERFACE
  20.  
  21.  
  22.  
  23.  
  24. PROCEDURE EnableIRQ   (i: WORD);
  25. PROCEDURE DisableIRQ  (i: WORD);
  26. FUNCTION  SetIRQVector(i: WORD; Vec: POINTER) : POINTER;
  27.  
  28. PROCEDURE DMASet   (Channel, Mode: WORD ; Buf: POINTER; Size: WORD);
  29. PROCEDURE DMARawSet(Channel, Mode, Page: BYTE; Offs, Size: WORD);
  30. PROCEDURE DMASetAsm;
  31.  
  32.  
  33.  
  34.  
  35. IMPLEMENTATION
  36.  
  37. USES Dos;
  38.  
  39.  
  40.  
  41.  
  42. {----------------------------------------------------------------------------}
  43. { PIC routines.                                                              }
  44. {____________________________________________________________________________}
  45.  
  46. PROCEDURE EnableIRQ(i: WORD);
  47.   BEGIN
  48.     IF i < 8 THEN
  49.       PORT[$21] := PORT[$21] AND (NOT (1 SHL i))
  50.     ELSE
  51.       BEGIN
  52.         PORT[$A1] := PORT[$A1] AND (NOT (1 SHL (i-8)));
  53.         PORT[$21] := PORT[$21] AND (NOT (1 SHL 2))
  54.       END;
  55.   END;
  56.  
  57.  
  58. PROCEDURE DisableIRQ(i: WORD);
  59.   BEGIN
  60.     IF i < 8 THEN
  61.       PORT[$21] := PORT[$21] OR (1 SHL i)
  62.     ELSE
  63.       BEGIN
  64.         PORT[$A1] := PORT[$A1] OR (1 SHL (i-8))
  65.       END;
  66.   END;
  67.  
  68.  
  69. FUNCTION SetIRQVector(i: WORD; Vec: POINTER) : POINTER;
  70.   VAR
  71.     p : POINTER;
  72.     j : WORD;
  73.   BEGIN
  74.     IF i < 8 THEN j := i + $08
  75.              ELSE j := i + $68;
  76.  
  77.     GetIntVec(j, p);
  78.     SetIntVec(j, Vec);
  79.     SetIRQVector := p;
  80.   END;
  81.  
  82.  
  83.  
  84.  
  85. {----------------------------------------------------------------------------}
  86. { DMA routines.                                                              }
  87. {____________________________________________________________________________}
  88.  
  89. {
  90.   AH = Channel
  91.   CH = Mode
  92.   CL = Page
  93.   BX = Offset
  94.   SI = Size
  95. }
  96.  
  97. PROCEDURE DMA16Set; ASSEMBLER;
  98.   CONST
  99.     PageRegTable : ARRAY[0..3] OF WORD = ( $00, $8B, $89, $8A );
  100.   ASM
  101.  
  102.         AND     AH,3
  103.  
  104.         SHR     CL,1
  105.         RCR     BX,1
  106.         ADD     CL,CL
  107.  
  108.         MOV  AL,AH;  ADD  AL,$04; OUT $D4,AL     { Disable DMA channel.                         }
  109.         XOR  AL,AL;               OUT $D8,AL     { Clear BYTE POINTER flip-flop to lower byte.  }
  110.         MOV  AL,AH;  ADD  AL,CH;  OUT $D6,AL     { DMA Mode register.                           }
  111.         XOR  DH,DH
  112.         MOV  DL,AH
  113.         ADD  DX,DX                               
  114.         ADD  DX,DX                               { Calculate DMA base port.                     }
  115.         ADD  DX,$C0
  116.  
  117.         MOV  AL,BL;               OUT  DX,AL     { Offset of the buffer, low & high bytes.      }
  118.         MOV  AL,BH;               OUT  DX,AL             
  119.  
  120.         PUSH DX
  121.  
  122.         MOV  DL,AH
  123.         ADD  DX,DX                               
  124.         MOV  BX,OFFSET PageRegTable
  125.         ADD  BX,DX                               { Calculate page register port.                }
  126.         MOV  DX,[BX]
  127.         MOV  AL,CL;               OUT  DX,AL     { Set DMA page.                                }
  128.  
  129.         POP  DX
  130.         INC  DX
  131.         INC  DX                                  { Calculate DMA counter port.                  }
  132.  
  133.         MOV  BX,SI
  134.         MOV  AL,BL;               OUT  DX,AL     { Size of the buffer minus 1, low & high byte. }
  135.         MOV  AL,BH;               OUT  DX,AL             
  136.         MOV  AL,AH;               OUT $D4,AL     { Enable DMA channel.                          }
  137.  
  138.   END;
  139.  
  140.  
  141. PROCEDURE DMA8Set; ASSEMBLER;
  142.   CONST
  143.     PageRegTable : ARRAY[0..3] OF WORD = ( $87, $83, $81, $82 );
  144.   ASM
  145.  
  146.         MOV  AL,AH;  ADD  AL,$04; OUT  $A,AL     { Disable DMA channel.                         }
  147.         XOR  AL,AL;               OUT  $C,AL     { Clear BYTE POINTER flip-flop to lower byte.  }
  148.         MOV  AL,AH;  ADD  AL,CH;  OUT  $B,AL     { DMA Mode register.                           }
  149.         XOR  DH,DH
  150.         MOV  DL,AH
  151.         ADD  DX,DX                               { Calculate DMA base port.                     }
  152.  
  153.         MOV  AL,BL;               OUT  DX,AL     { Offset of the buffer, low & high bytes.      }
  154.         MOV  AL,BH;               OUT  DX,AL             
  155.  
  156.         PUSH DX
  157.  
  158.         MOV  BX,OFFSET PageRegTable
  159.         ADD  BX,DX                               { Calculate page register port.                }
  160.         MOV  DX,[BX]
  161.         MOV  AL,CL;               OUT  DX,AL     { Set DMA page.                                }
  162.  
  163.         POP  DX
  164.         INC  DX                                  { Calculate DMA counter port.                  }
  165.  
  166.         MOV  BX,SI
  167.         MOV  AL,BL;               OUT  DX,AL     { Size of the buffer minus 1, low & high byte. }
  168.         MOV  AL,BH;               OUT  DX,AL             
  169.         MOV  AL,AH;               OUT  $A,AL     { Enable DMA channel.                          }
  170.  
  171.   END;
  172.  
  173.  
  174. PROCEDURE DMASetAsm; ASSEMBLER;
  175.   ASM
  176.  
  177.                 CMP     AH,2
  178.                 JZ      @@Fin
  179.                 CMP     AH,4
  180.                 JZ      @@Fin
  181.                 JB      @@8bit
  182.                  CALL   DMA16Set
  183.                 JMP    @@Fin
  184. @@8bit:          CALL   DMA8Set
  185.  
  186. @@Fin:
  187.  
  188.   END;
  189.  
  190.  
  191. PROCEDURE DMARawSet(Channel, Mode, Page: BYTE; Offs, Size: WORD); ASSEMBLER;
  192.   ASM
  193.  
  194.         MOV     AH,[Channel]
  195.         MOV     CH,[Mode]
  196.         MOV     CL,[Page]
  197.         MOV     BX,[Offs]
  198.         MOV     SI,[Size]
  199.  
  200.         CALL    DMASetAsm
  201.  
  202.   END;
  203.  
  204.  
  205. PROCEDURE DMASet(Channel, Mode: WORD ; Buf: POINTER; Size: WORD);
  206.   VAR
  207.     Segm : WORD;
  208.     Offs : WORD;
  209.   BEGIN
  210.  
  211.     Segm := SEG(Buf^) AND $F000;
  212.     Offs := SEG(Buf^) AND $0FFF;
  213.  
  214.     IF Offs > 65535 - OFS(Buf^) THEN
  215.       BEGIN
  216.         INC(Segm, $1000);
  217.         Offs := WORD(Offs - 65536 + OFS(Buf^));
  218.       END
  219.     ELSE
  220.       BEGIN
  221.         Offs := Offs + OFS(Buf^);
  222.       END;
  223.  
  224.     DEC(Size);
  225.  
  226.     DMARawSet(Channel, Mode, Segm SHR 12, Offs, Size);
  227.  
  228.   END;
  229.  
  230.  
  231.  
  232.  
  233. END.
  234.